package com.yunbiao.ybbusstopplate.play_sync;

import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Log;

import com.alibaba.fastjson.JSONObject;
import com.blankj.utilcode.util.GsonUtils;
//import com.janev.chongqing_bus_app.data_sync.NetController;
//import com.janev.chongqing_bus_app.db.Material;
//import com.janev.chongqing_bus_app.db.Time;
//import com.janev.chongqing_bus_app.system.Path;
//import com.janev.chongqing_bus_app.tcp.StorageChecker;
//import com.janev.chongqing_bus_app.utils.BaseTimer;
//import com.janev.chongqing_bus_app.utils.ProgramLoader;
import com.xuhao.didi.core.iocore.interfaces.ISendable;
import com.xuhao.didi.core.pojo.OriginalData;

import com.xuhao.didi.socket.client.sdk.OkSocket;
import com.xuhao.didi.socket.common.interfaces.common_interfacies.server.IClient;
import com.xuhao.didi.socket.common.interfaces.common_interfacies.server.IClientIOCallback;
import com.xuhao.didi.socket.common.interfaces.common_interfacies.server.IClientPool;
import com.xuhao.didi.socket.common.interfaces.common_interfacies.server.IServerActionListener;
import com.xuhao.didi.socket.common.interfaces.common_interfacies.server.IServerManager;
import com.xuhao.didi.socket.common.interfaces.common_interfacies.server.IServerShutdown;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

/**
 * 主屏幕Socket服务，用于通知副屏同步播放
 */
public class ServerSocket {

    private static final String TAG = "ServerSocket";

    public static final int SERVER_PORT = 10000;

    private final IServerManager iServerManager;

    private Disposable disposable;

//    public static final LinkedHashMap<Material, List<Time>> materialMap = new LinkedHashMap<>();
//
//    private Material material;
//
//    private BaseTimer baseTimer;

    private static final class Holder {
        public static final ServerSocket INSTANCE = new ServerSocket();
    }

    public static ServerSocket getInstance() {
        return Holder.INSTANCE;
    }

    private ServerSocket() {
        // 创建连接配置
        // ConnectionInfo info = new ConnectionInfo(serverIp, SERVER_PORT);
        iServerManager = OkSocket.server(SERVER_PORT).registerReceiver(iServerActionListener);

    }

    private final StringBuilder stringBuilder = new StringBuilder();

    private Runnable runnable;

    public String getMessage() {
        return stringBuilder.toString();
    }

    public void setRunnable(Runnable runnable) {
        this.runnable = runnable;
    }

    public void runUpdate() {
        if (runnable != null) {
            runnable.run();
        }
    }

    public void inputLog(String log) {
        stringBuilder.append("\n").append(log);
        runUpdate();
    }

    public void start() {
        if (!isLive()) {
            iServerManager.listen();
        }
    }

    public void stop() {
        if (isLive()) {
            iServerManager.shutdown();
        }
    }

    public boolean isLive() {
        return iServerManager.isLive();
    }

    public void send(JSONObject jsonObject) {
        if (jsonObject != null && !jsonObject.isEmpty()) {
            send(jsonObject.toJSONString());
        }
    }

    public void send(String s) {
        if (!TextUtils.isEmpty(s)) {
            Log.d(TAG, "主屏幕发送数据: " + s);
            send(new SocketDataBean(s));
        }
    }

    public void send(SocketDataBean msgDataBean) {
        if (isLive()) {
            iServerManager.getClientPool().sendToAll(msgDataBean);
        }
    }

    private final IServerActionListener iServerActionListener = new IServerActionListener() {
        @Override
        public void onServerListening(int i) {
            Log.d(TAG, "onServerListening: " + i);
            stringBuilder.append("\n").append("服务已启动：").append(i);
            runUpdate();
        }

        @Override
        public void onClientConnected(IClient iClient, int i, IClientPool iClientPool) {
            Log.d(TAG, "onClientConnected: " + iClient.getHostName() + " --- " + i);
            stringBuilder.append("\n").append("有设备连接：").append(iClient.getHostIp());
            if (disposable != null && !disposable.isDisposed()) {
                disposable.dispose();
                disposable = null;
            }
//            if(baseTimer==null){
//                baseTimer = new BaseTimer();
//            }
//            baseTimer.cancelTimer();
//            baseTimer.getTimer();
//            TimerTask timerTask = new TimerTask() {
//                @Override
//                public void run() {
//                    startSendFile();
//                }
//            };
//            baseTimer.getTimer().schedule(timerTask, 10000);

            runUpdate();

        }

        @Override
        public void onClientDisconnected(IClient iClient, int i, IClientPool iClientPool) {
            Log.d(TAG, "onClientDisconnected: " + iClient.getHostName() + " --- " + i);
            iClient.removeAllIOCallback();
            stringBuilder.append("\n").append("设备已断开：").append(iClient.getHostIp());
            if (disposable != null && !disposable.isDisposed()) {
                disposable.dispose();
                disposable = null;
            }
            runUpdate();
        }

        @Override
        public void onServerWillBeShutdown(int i, IServerShutdown iServerShutdown, IClientPool iClientPool, Throwable throwable) {
            Log.d(TAG, "onServerWillBeShutdown: " + i + " --- " + (throwable.getMessage()));
            iServerShutdown.shutdown();
            stringBuilder.append("\n").append("服务即将中断：").append(i);
            runUpdate();
        }

        @Override
        public void onServerAlreadyShutdown(int i) {
            Log.d(TAG, "onServerAlreadyShutdown: " + i);
            stringBuilder.append("\n").append("服务已中断：").append(i);
            runUpdate();
        }

    };

    public void updateSendFile() {
        if (disposable != null && !disposable.isDisposed()) {
            disposable.dispose();
            disposable = null;
        }
        startSendFile();
    }

    public void startSendFile() {

//        List<Material> materialList = ProgramLoader.loadDownloadList();
//        if (materialList.isEmpty()) {
//            SocketUtil.d(TAG, "start: 发送列表为空");
//            return;
//        }
//        if (disposable != null && !disposable.isDisposed()) {
//            SocketUtil.d(TAG, "start: 发送正在进行");
//            return;
//        }
//
//
//        disposable = Observable.fromIterable(materialList)
//                .subscribeOn(Schedulers.io())
//                .observeOn(AndroidSchedulers.mainThread())
//                //  .repeatWhen(objectObservable -> objectObservable.delay(5, TimeUnit.SECONDS))//三秒无限重试
//                .subscribe(
//                        this::sendMaterialFile,
//                        Throwable::printStackTrace,
//                        () -> System.out.println("Completed!")
//                );

    }

    // 1MB chunks
    private static final int BUFFER_SIZE = 1024 * 1024;

    // 发送文件的方法
//    public void sendMaterialFile(Material material) {
//        String materialPath = Path.getMaterialPath(material);
//        File file = new File(materialPath);
//        // 确保文件存在且可读
//        if (file == null || !file.exists() || !file.canRead()) {
//            Log.d(TAG, "播放文件不存在： " + file.getPath());
//            return;
//        }
//        Log.d(TAG, "媒体名称： " + material.getName() + file.getName());
//        // 发文件给副屏
//        try {
//            material.setSize(file.length());
//            FileInputStream fileInputStream = new FileInputStream(file);
//            int len = BUFFER_SIZE ;
//            byte[] buffer = new byte[len];
//            int bytesRead;
//            send(material, file.getName(), new byte[0], 0);
//            while ((bytesRead = fileInputStream.read(buffer)) != -1) {
//                Log.d(TAG, "文件数据包： " + buffer.length + "," + file.length() + "," + bytesRead);
//                //outputStream.write(buffer, 0, bytesRead);
//                if (bytesRead < len) {
//                    byte[] flushBuffer = new byte[bytesRead];
//                    System.arraycopy(buffer, 0, flushBuffer, 0, bytesRead);
//                    send(material, file.getName(), flushBuffer, 1);
//                }else {
//                    send(material, file.getName(), buffer, 1);
//                }
//                SystemClock.sleep(1);
//            }
//           // send(material, file.getName(), new byte[0], -1);
//            fileInputStream.close();
//            // outputStream.close();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//
//    }

    /**
     * 发文件给副屏
     *
     * @param material
     */
//    private void send(Material material, String fileName, byte[] data, int flag) {
//        if (material != null) {
//            String jsonString = SocketUtil.getFileData( fileName,data,flag,material);
//            send(jsonString);
//        }
//    }

//    private Observable<Integer> playProgram(Map.Entry<Material, List<Time>> entry, ProgramFile programFile) {
//        return Observable.create(emitter -> {
//            material = entry.getKey();
//            if (material.getProgramId().equals(programFile.getMaterial().getProgramId()) && material.getId().equals(programFile.getMaterial().getId())) {
//                sendMaterialFile(material);
//            }
//        });
//    }

}
